/*
 * AudioLoad.java
 *
 * 02/11/2009
 */
package kg.sound.player.media;

import java.io.File;
import java.net.URL;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

/**
 * @author fernando
 */
public final class AudioLoader {

	private AudioLoader() {
	}
	
	public static AudioInputStream createAudioInputStream(URL url)
			throws Exception {
		return AudioSystem.getAudioInputStream(url);
	}
	
	public static AudioInputStream createAudioInputStream(String filename)
			throws Exception {
		return AudioSystem.getAudioInputStream(new File(filename));
	}
	
	public static AudioInputStream createAudioInputStream(File file)
			throws Exception {
		return AudioSystem.getAudioInputStream(file);
	}

	public static Clip loadClip(AudioInputStream in) throws Exception {

		/* Get the audio format for the data in the stream */
		AudioFormat format = in.getFormat();
		
        /* convert ULAW/ALAW formats to PCM format */
        if ((format.getEncoding() == AudioFormat.Encoding.ULAW) ||
            (format.getEncoding() == AudioFormat.Encoding.ALAW)) {
			AudioFormat decodedFormat =
					new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
							format.getSampleRate(),
							format.getSampleSizeInBits() * 2,
							format.getChannels(), 
							format.getFrameSize() * 2,
							format.getFrameRate(), true);  // big endian
			
			/* update stream and format details */
			in = AudioSystem.getAudioInputStream(decodedFormat, in);
			format = decodedFormat;
        }

		/* Gather information for line creation */
		DataLine.Info info = new DataLine.Info(Clip.class, format);
		
        /*-
         * It's also possible to check in advance whether line is support   
         * 
        if (!AudioSystem.isLineSupported(info)) {
        	// do whatever should be done
        }
 		*/

		/* Create an empty clip using that line information */
		Clip clip = (Clip) AudioSystem.getLine(info);

		/* Open the audio stream as a clip; now it's ready to play */
		clip.open(in);
		
		return clip;
	}

	public static SourceDataLine loadSource(AudioInputStream in) throws Exception {

		/* Get the audio format for the data in the stream */
		AudioFormat format = in.getFormat();
		
        /* convert ULAW/ALAW formats to PCM format */
//        if ((format.getEncoding() == AudioFormat.Encoding.ULAW) ||
//            (format.getEncoding() == AudioFormat.Encoding.ALAW)) {
			AudioFormat decodedFormat = 
					new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
							format.getSampleRate(), 
							16, 
							format.getChannels(),
							format.getChannels() * 2, 
							format.getSampleRate(),
							false); // big endian
			
			
			/* update stream and format details */
			in = AudioSystem.getAudioInputStream(decodedFormat, in);
			format = decodedFormat;
//        }

		/* Gather information for line creation */
		DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
		
        /*-
         * It's also possible to check in advance whether line is support   
         * 
        if (!AudioSystem.isLineSupported(info)) {
        	// do whatever should be done
        }
 		*/

		/* Get a line of the required format */
        SourceDataLine source = (SourceDataLine) AudioSystem.getLine(info);
        
        source.open(format);
		
		return source;
	}
}
